home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / simula / books / books.lha / kirkerud / settools.sim < prev    next >
Text File  |  1993-08-16  |  20KB  |  693 lines

  1. class settools;
  2.  
  3. begin
  4.  
  5.  
  6. !********************************************
  7. !*                        *
  8. !*                 Element                  *
  9. !*                        *
  10. !********************************************;
  11.  
  12.   class element;
  13.       virtual: text procedure key;
  14.                Boolean procedure precedes, equiv;
  15.                procedure display;
  16.     begin
  17.  
  18.       text procedure key; key :- notext;
  19.  
  20.       Boolean procedure precedes(el); ref(element) el; 
  21.         precedes := false;       
  22.  
  23.       Boolean procedure equiv(el); ref(element) el; 
  24.         equiv := false;       
  25.  
  26.       procedure display; outtext(key);
  27.  
  28.     end of element;
  29.  
  30.  
  31. !********************************************
  32. !*                        *
  33. !*                Sequence                  *
  34. !*                        *
  35. !********************************************;
  36.  
  37.   element class sequence;
  38.  
  39.     begin
  40.       
  41.       ref(element) head_element;
  42.       ref(sequence) tail_sequence;
  43.  
  44.       Boolean procedure is_empty;
  45.         is_empty := head_element == none;
  46.  
  47.       integer procedure size;
  48.         size := if head_element == none then 0 else
  49.             if tail_sequence == none then 1
  50.                 else 1 + tail_sequence.size;
  51.  
  52.       ref(element) procedure element_number(elnr); integer elnr;
  53.         element_number :- 
  54.             if elnr <= 0 then none else
  55.         if elnr = 1 then head_element else
  56.             if tail_sequence == none then none
  57.             else tail_sequence.element_number(elnr-1);
  58.  
  59.       procedure append(el); ref(element) el;
  60.         if head_element == none then head_element :- el 
  61.         else begin
  62.           if tail_sequence == none then tail_sequence :- new sequence;
  63.           tail_sequence.append(el);
  64.         end;
  65.  
  66.       procedure display;
  67.         begin ref(element) el;
  68.           outtext("<"); 
  69.           el :- first_element;
  70.           while el =/= none do
  71.             begin 
  72.               el.display; el :- next_element;
  73.               if el =/= none then outtext(", ");
  74.             end;
  75.           outtext(">");
  76.         end;
  77.  
  78.       ref(sequence) next_sequence, curr_sequence,
  79.                     kept_next_sequence, kept_curr_sequence;
  80.  
  81.       ref(element) procedure first_element;
  82.         begin 
  83.           first_element :- head_element; 
  84.           curr_sequence :- this sequence;  
  85.           next_sequence :- tail_sequence;
  86.         end;
  87.  
  88.       ref(element) procedure next_element;
  89.         if next_sequence == none then next_element :- none
  90.         else begin
  91.           next_element  :- next_sequence.head; 
  92.           curr_sequence :- next_sequence;
  93.           next_sequence :- next_sequence.tail_sequence;
  94.         end;
  95.  
  96.       procedure remember_next;
  97.         begin
  98.           kept_next_sequence :- next_sequence;
  99.           kept_curr_sequence :- curr_sequence;
  100.         end;
  101.  
  102.       procedure restore_next;
  103.         begin
  104.           next_sequence :- kept_next_sequence;
  105.           curr_sequence :- kept_curr_sequence;
  106.         end;
  107.  
  108.       procedure remove_current;
  109.         if next_sequence =/= none then
  110.           begin
  111.             curr_sequence.head_element  :- next_sequence.head_element;
  112.             curr_sequence.tail_sequence :- next_sequence.tail_sequence;
  113.             next_sequence :- curr_sequence;
  114.           end
  115.         else curr_sequence.head_element :- none;
  116.  
  117.       procedure remove_head;
  118.         begin
  119.           head_element :- none;
  120.           if tail_sequence =/= none then
  121.             begin
  122.               head_element  :- tail_sequence.head_element;
  123.               tail_sequence :- tail_sequence.tail_sequence; 
  124.             end;
  125.         end;
  126.  
  127.       procedure remove_last;
  128.         if tail_sequence == none then head_element :- none
  129.       else begin
  130.              tail_sequence.remove_last;
  131.              if tail_sequence.is_empty then tail_sequence :- none;
  132.       end; 
  133.  
  134.       ref(element) procedure last_element;
  135.         last_element :- if tail_sequence == none then head_element
  136.             else tail_sequence.last_element;
  137.  
  138.       ref(element) procedure head;
  139.         head :- head_element;
  140.  
  141.       ref(sequence) procedure tail;
  142.         tail :- if tail_sequence =/= none then tail_sequence
  143.                 else new sequence;
  144.  
  145.     end of sequence;
  146.  
  147.  
  148. !********************************************
  149. !*                        *
  150. !*                Stack                     *
  151. !*                        *
  152. !********************************************;
  153.  
  154.   element class stack;
  155.  
  156.     begin
  157.       
  158.       ref(element) head_element;
  159.       ref(stack)   tail_stack;
  160.  
  161.       Boolean procedure is_empty;
  162.         is_empty := head_element == none;
  163.  
  164.       integer procedure size;
  165.         size := if head_element == none then 0 else
  166.             if tail_stack == none then 1
  167.                 else 1 + tail_stack.size;
  168.  
  169.       procedure push(el); ref(element) el;
  170.         if head_element == none then head_element :- el 
  171.         else begin
  172.           if tail_stack == none then tail_stack :- new stack;
  173.           tail_stack.push(head_element);
  174.           head_element :- el;
  175.         end;
  176.         
  177.       ref(element) procedure pop;
  178.         begin
  179.           pop :- head_element;  head_element :- none;
  180.           if tail_stack == none then head_element :- none else
  181.             begin
  182.               head_element :- tail_stack.head_element;
  183.               tail_stack   :- tail_stack.tail_stack;
  184.             end;
  185.         end;
  186.  
  187.       ref(element) procedure top;
  188.         top :- head_element;
  189.  
  190.       procedure display;
  191.         begin ref(element) el;
  192.           outtext("<"); 
  193.           el :- head_element;
  194.           if el =/= none then
  195.             begin 
  196.               el.display; 
  197.               if tail_stack =/= none then 
  198.                 tail_stack.display;
  199.             end;
  200.           outtext(">");
  201.         end;
  202.  
  203.     end of stack;
  204.  
  205.  
  206. !********************************************
  207. !*                        *
  208. !*            Ordered_bag                   *
  209. !*                        *
  210. !********************************************;
  211.  
  212.   element class Ordered_bag;
  213.  
  214.     begin
  215.       
  216.       ref(element)     head_element;
  217.       ref(Ordered_bag) tail_bag;
  218.  
  219.       Boolean procedure is_empty;
  220.         is_empty := head_element == none;
  221.  
  222.       integer procedure size;
  223.         size := if head_element == none then 0 else
  224.             if tail_bag == none then 1
  225.                 else 1 + tail_bag.size;
  226.  
  227.       procedure add_element(el); ref(element) el;
  228.         if head_element == none 
  229.         then head_element :- el 
  230.         else begin
  231.           if tail_bag == none then tail_bag :- new Ordered_bag;
  232.           if el.precedes(head_element) then
  233.             begin 
  234.               tail_bag.add_element(head_element); 
  235.               head_element :- el;
  236.             end
  237.           else if not el.equiv(head_element)
  238.             then tail_bag.add_element(el)
  239.         end;
  240.  
  241.       procedure display;
  242.         begin ref(element) el;
  243.           outtext("{"); 
  244.           el :- first_element;
  245.           while el =/= none do
  246.             begin 
  247.               el.display; el :- next_element;
  248.               if el =/= none then outtext(", ");
  249.             end;
  250.           outtext("}");
  251.         end;
  252.  
  253.       ref(ordered_bag) next_bag, curr_bag, kept_next_bag, kept_curr_bag;
  254.  
  255.       ref(element) procedure first_element;
  256.         begin 
  257.           first_element :- head_element; 
  258.           curr_bag      :- this Ordered_bag;  
  259.           next_bag      :- tail_bag;
  260.         end;
  261.  
  262.       ref(element) procedure next_element;
  263.         if next_bag == none then next_element :- none
  264.         else begin
  265.           next_element  :- next_bag.head_element; 
  266.           curr_bag      :- next_bag;
  267.           next_bag      :- next_bag.tail_bag;
  268.         end;
  269.  
  270.       procedure set_current;
  271.         remember_next;
  272.  
  273.       procedure reset_current;
  274.         restore_next;
  275.  
  276.       procedure remember_next;
  277.         begin
  278.           kept_next_bag :- next_bag;
  279.           kept_curr_bag :- curr_bag;
  280.         end;
  281.  
  282.       procedure restore_next;
  283.         begin
  284.           next_bag :- kept_next_bag;
  285.           curr_bag :- kept_curr_bag;
  286.         end;
  287.  
  288.       procedure remove_current;
  289.         if next_bag =/= none then
  290.           begin
  291.             curr_bag.head_element  :- next_bag.head_element;
  292.             curr_bag.tail_bag      :- next_bag.tail_bag;
  293.             next_bag               :- curr_bag;
  294.           end
  295.         else curr_bag.head_element :- none;
  296.  
  297.       ref(element) procedure last_element;
  298.         last_element :- if tail_bag == none then head_element
  299.             else tail_bag.last_element;
  300.  
  301.     end of Ordered_bag;
  302.  
  303.  
  304. !********************************************
  305. !*                        *
  306. !*                Basis_set                 *
  307. !*                        *
  308. !********************************************;
  309.  
  310.   element class basis_set;
  311.  
  312.       virtual: Boolean procedure      is_empty,
  313.                       is_member,
  314.                       add_element_ok,
  315.                       remove_element_ok;
  316.            integer procedure      size;
  317.               procedure           add_element, 
  318.                        remove_add_element, 
  319.                        remove_element, 
  320.                                       set_current,
  321.                                       reset_current,
  322.                        for_each_element;
  323.               ref(element) procedure find_element, 
  324.                        first_element, 
  325.                       next_element;
  326.  
  327.     begin
  328.  
  329.       Boolean procedure add_element_ok(an_element);
  330.           ref(element) an_element; 
  331.         begin Boolean exists;
  332.           add_element(an_element, exists);
  333.           add_element_ok := not exists;
  334.         end;
  335.  
  336.       Boolean procedure remove_element_ok(key);
  337.           text key;
  338.         begin Boolean no_such;
  339.           remove_element(key, no_such);
  340.           remove_element_ok := not no_such;
  341.         end;
  342.  
  343.       procedure display;
  344.         begin ref(element) an_element;
  345.           outtext("{"); 
  346.           an_element :- first_element;
  347.           while an_element =/= none do
  348.             begin 
  349.               an_element.display; 
  350.               an_element :- next_element;
  351.               if an_element =/= none then outtext(", ");
  352.             end;
  353.           outtext("}");
  354.         end;
  355.  
  356.       procedure for_each_element(p); procedure p;
  357.         begin ref(element) an_element;
  358.           an_element :- first_element;
  359.           while an_element =/= none do
  360.             begin
  361.               p(an_element);
  362.               an_element :- next_element;
  363.             end;
  364.         end;
  365.  
  366.     end of basis_set;
  367.  
  368.  
  369. !********************************************
  370. !*                        *
  371. !*                 Set                      *
  372. !*                        *
  373. !********************************************;
  374.  
  375.   basis_set class set;
  376.     begin
  377.       
  378.       ref(element) head;
  379.       ref(set) tail;
  380.  
  381.       Boolean procedure is_empty;
  382.         is_empty := head == none;
  383.  
  384.       Boolean procedure is_member(key); text key;
  385.         if head == none then is_member := false
  386.         else if head.key = key then is_member := true
  387.         else if tail == none then is_member := false
  388.         else is_member := tail.is_member(key);
  389.  
  390.       integer procedure size;
  391.         size := if head == none then 0 else
  392.             if tail == none then 1
  393.                 else 1 + tail.size;
  394.  
  395.       procedure add_element(an_element, element_exists); 
  396.           name element_exists; 
  397.           ref(element) an_element; Boolean element_exists;
  398.         if head == none or an_element == none then 
  399.           begin head :- an_element; element_exists := false end else
  400.         if head.key = an_element.key then element_exists := true 
  401.         else begin
  402.             if tail == none then tail :- new set;
  403.             tail.add_element(an_element, element_exists);
  404.           end;
  405.  
  406.       procedure remove_add_element(an_element); ref(element) an_element; 
  407.         if head == none or else head.key = an_element.key 
  408.           then head :- an_element
  409.           else begin
  410.             if tail == none then tail :- new set;
  411.             tail.remove_add_element(an_element);
  412.           end;
  413.  
  414.       procedure remove_element(key, no_such_element);
  415.           name no_such_element; 
  416.       text key; Boolean no_such_element;
  417.         if head == none then no_such_element := true else
  418.         if head.key = key then
  419.           begin 
  420.             no_such_element := false;
  421.             if tail == none 
  422.               then head :- none
  423.               else begin head :- tail.head; tail :- tail.tail end;
  424.           end else
  425.         if tail == none then no_such_element := true 
  426.         else begin
  427.             tail.remove_element(key, no_such_element); 
  428.             if tail.is_empty then tail :- none;
  429.           end of remove_element;
  430.  
  431.       ref(element) procedure find_element(key); text key;
  432.         find_element :-
  433.           if head     == none then none else
  434.           if head.key =  key  then head else
  435.           if tail     == none then none 
  436.           else tail.find_element(key);
  437.  
  438.       ref(set) next_set, kept_next_set;
  439.       ref(stack) next_stack; 
  440.  
  441.       ref(element) procedure first_element;
  442.         begin first_element :- head; push_next; next_set :- tail end;
  443.  
  444.       ref(element) procedure next_element;
  445.         if next_set == none 
  446.         then begin
  447.             next_element :- none;
  448.             pop_next;
  449.           end
  450.         else begin
  451.           next_element :- next_set.head; 
  452.           next_set     :- next_set.tail;
  453.         end;
  454.  
  455.       procedure push_next;
  456.         next_stack.push(next_set);
  457.  
  458.       procedure pop_next;
  459.         next_set :- if next_stack =/= none then next_stack.pop else none;
  460.  
  461.       procedure set_current;
  462.         kept_next_set :- next_set;
  463.  
  464.       procedure reset_current;
  465.         next_set :- kept_next_set;
  466.  
  467.       next_stack :- new stack;
  468.  
  469.     end of set;
  470.  
  471.  
  472.  
  473. !********************************************
  474. !*                        *
  475. !*             Ordered_set                  *
  476. !*                        *
  477. !********************************************;
  478.  
  479.   basis_set class ordered_set;
  480.  
  481.     begin
  482.       
  483.       ref(table) element_table;
  484.  
  485.       Boolean procedure is_empty;
  486.         is_empty := element_table.is_empty;
  487.  
  488.       integer procedure size;
  489.         size := element_table.size;
  490.  
  491.       procedure add_element(an_element, element_exists); 
  492.           name element_exists; 
  493.           ref(element) an_element; Boolean element_exists;
  494.         begin 
  495.           if element_table.is_full then 
  496.              element_table :- element_table.increase; 
  497.           element_table.add_element(an_element, element_exists);
  498.         end;        
  499.  
  500.       procedure remove_add_element(an_element); ref(element) an_element; 
  501.         begin 
  502.           if element_table.is_full then 
  503.              element_table :- element_table.increase; 
  504.           element_table.remove_add_element(an_element);
  505.         end;        
  506.  
  507.       procedure remove_element(key, no_such_element);
  508.           name no_such_element; text key; Boolean no_such_element;
  509.         begin
  510.           element_table.remove_element(key, no_such_element);
  511.           if element_table.is_almost_empty then 
  512.              element_table :- element_table.decrease; 
  513.         end;
  514.  
  515.       ref(element) procedure find_element(key); text key;
  516.         find_element :- element_table.find_element(key); 
  517.  
  518.       ref(element) procedure first_element;
  519.         first_element :- element_table.first_element;
  520.  
  521.       ref(element) procedure next_element;
  522.         next_element :- element_table.next_element;
  523.  
  524.       procedure set_current;
  525.         element_table.set_current;
  526.  
  527.       procedure reset_current;
  528.         element_table.reset_current;
  529.  
  530.       element_table :- new table(1);
  531.  
  532.     end of ordered_set;
  533.  
  534.  
  535. !********************************************
  536. !*                        *
  537. !*                Table                     *
  538. !*                        *
  539. !********************************************;
  540.  
  541.   class table(table_size); integer table_size;
  542.  
  543.     begin
  544.       
  545.       ref(element) array the_elements(1 : table_size);
  546.  
  547.       integer number_of_elements;
  548.  
  549.       procedure add_element(an_element, element_exists); 
  550.           name element_exists; 
  551.           ref(element) an_element; Boolean element_exists;
  552.         begin integer index, i; 
  553.           index := find_index(an_element.key);
  554.           if index <= number_of_elements and then
  555.            the_elements(index).key = an_element.key then 
  556.             element_exists := true
  557.           else begin
  558.               for i := number_of_elements step -1 until index do
  559.                 the_elements(i + 1) :- the_elements(i);
  560.               number_of_elements := number_of_elements + 1;
  561.               the_elements(index) :- an_element;
  562.               element_exists := false;
  563.             end;
  564.         end;        
  565.  
  566.       procedure remove_add_element(an_element); ref(element) an_element;
  567.         begin integer index, i; 
  568.           index := find_index(an_element.key);
  569.           if index <= number_of_elements and then
  570.            the_elements(index).key = an_element.key then 
  571.             the_elements(index) :- an_element
  572.           else begin
  573.               for i := number_of_elements step -1 until index do
  574.                 the_elements(i + 1) :- the_elements(i);
  575.               number_of_elements := number_of_elements + 1;
  576.               the_elements(index) :- an_element;
  577.             end;
  578.         end;        
  579.  
  580.       procedure remove_element(key, no_such_element); 
  581.           name no_such_element; text key; Boolean no_such_element;
  582.         begin integer index, i; 
  583.           index := find_index(key);
  584.           if index <= number_of_elements and then
  585.            the_elements(index).key = key then
  586.             begin
  587.               for i := index + 1 step 1 until number_of_elements do
  588.                 the_elements(i - 1) :- the_elements(i);
  589.               number_of_elements := number_of_elements - 1;
  590.               no_such_element := false;
  591. ! Endring 12.11.88:    ;
  592.               if index < next_in_table 
  593.                 then next_in_table := next_in_table - 1;
  594.             end
  595.           else no_such_element := true;
  596.         end;
  597.  
  598.       ref(element) procedure find_element(key); text key;
  599.         if is_empty then find_element :- none else
  600.         begin integer index; 
  601.           index := find_index(key);
  602.           find_element :- 
  603.         if index <= number_of_elements and then
  604.            the_elements(index).key = key then the_elements(index) 
  605.             else none;
  606.         end;
  607.  
  608.       integer next_in_table, kept_next_in_table;
  609.  
  610.       ref(element) procedure first_element;
  611.         begin 
  612.           first_element :- element_number(1);
  613.           next_in_table  := 2;
  614.         end;
  615.  
  616.       ref(element) procedure next_element;
  617.         begin 
  618.           next_element :- element_number(next_in_table);
  619.           next_in_table := next_in_table + 1;
  620.         end;
  621.  
  622.       procedure set_current;
  623.         kept_next_in_table := next_in_table;
  624.  
  625.       procedure reset_current;
  626.         next_in_table := kept_next_in_table;
  627.  
  628.       integer procedure size;
  629.         size := number_of_elements;
  630.  
  631.       Boolean procedure is_empty;
  632.         is_empty := number_of_elements = 0;
  633.  
  634.       Boolean procedure is_full;
  635.         is_full := number_of_elements = table_size;
  636.  
  637.       Boolean procedure is_almost_empty;
  638.         is_almost_empty := (number_of_elements < table_size//4
  639.                 and table_size > 1);
  640.  
  641.       ref(element) procedure element_number(number); integer number;
  642. ! Rettet 1.april 1992:   ;
  643.         element_number :- if not(1 <= number and number <= number_of_elements)
  644.                           then none
  645.                           else the_elements(number);
  646.  
  647.       ref(table) procedure increase;
  648.         begin ref(table) aux_table; integer index;
  649.           aux_table :- new table(2 * table_size);
  650.           for index := 1 step 1 until number_of_elements do
  651.             aux_table.the_elements(index) :- the_elements(index);
  652.           aux_table.number_of_elements := number_of_elements; 
  653. ! Rettet 12.11.88:   ;
  654.           aux_table.next_in_table := next_in_table;
  655.           increase :- aux_table;
  656.         end;
  657.         
  658.       ref(table) procedure decrease;
  659.         begin ref(table) aux_table; integer index;
  660.           aux_table :- new table(table_size//2);
  661.           for index := 1 step 1 until number_of_elements do
  662.             aux_table.the_elements(index) :- the_elements(index);
  663.           decrease :- aux_table;
  664.           aux_table.number_of_elements := number_of_elements; 
  665. ! Rettet 12.11.88:   ;
  666.           aux_table.next_in_table := next_in_table;
  667.         end;
  668.         
  669.       integer procedure find_index(key); text key;
  670.         if number_of_elements = 0 or else  
  671.            the_elements(number_of_elements).key < key 
  672.         then find_index := number_of_elements + 1 
  673.         else begin integer b, t, m;
  674.           b := 0; t := number_of_elements;
  675.           while b + 1 ne t do
  676.             begin
  677.               m := (b + t)//2;
  678.               if the_elements(m).key < key
  679.                 then b := m else t := m;
  680.             end;
  681.           find_index := t;
  682.         end;
  683.  
  684.      number_of_elements := 0;  
  685.  
  686.    end of table;
  687.  
  688.  
  689.  
  690. end of settools;
  691.  
  692.  
  693.